<script setup lang="ts">
import { reactive, ref, computed, Reactive } from "vue"
import { IPackNifi } from "src/inter"
import { ElForm, ElFormItem, ElButton, ElCheckboxGroup, ElCheckbox, ElSelectV2, ElInput, ElMessage, ElTabs, ElTabPane } from "element-plus"
import { Edge } from "@ui/pack-antv-x6";
import { diff } from "../../util"
import { DEFAULT_STATUS_COLOR, DEFAULT_STATUS_NAME, DEFAULT_CELL_NAME } from "../metadata"
import { snakeCase, has, get, set } from "lodash-es"
import { t } from "../../i18n/index"
import HexEl from "../../components/content/hex.vue"
// import { BoxScroll } from "ui-base"
// import processorsUrl from "../../svg/cpu-duotone.svg?url"

const { nifi, cell: edge, disabled } = defineProps<IPackNifi.CellProps & { cell: Edge }>();
//
const tabname = ref('property')
//
const id = edge.id;
const cd = nifi.cells.get(id);
const isNew = cd == undefined;
const groupId = nifi.group.id;
// @ts-ignore
const isGroup = (name: string) => [DEFAULT_CELL_NAME.processGroups.en, DEFAULT_CELL_NAME.remoteProcessGroups.en].includes(name);
// 获取处理组数据 
const getGroupData = async (name: string, id: string, type: "in" | "out" = 'in', target: Reactive<any[]>) => {
    const url = `/nifi-api/flow/${name}/${id}`;
    try {
        const res = await nifi.api.get(url);
        const processGroupFlow = res.processGroupFlow;
        const ports = type == 'in' ? processGroupFlow.flow.inputPorts : processGroupFlow.flow.outputPorts;
        // const inputPorts = processGroupFlow.flow.inputPorts.map((d:any) => ({value:d.id,label:d.component.name}));
        // const outputPorts = processGroupFlow.flow.outputPorts.map((d:any) => ({value:d.id,label:d.component.name}));
        const t = ports.map((d: any) => ({ value: d.id, label: d.component.name }));
        target.push(...t)
        type == 'in' ? model.destination.id = t[0]?.value : model.source.id = t[0]?.value;
    } catch (error) {
        ElMessage.error(t('cells-connections-form-getgroup-failed', { error }));
        console.error(error)
    }
}
// 起始节点
const sid = edge.getSourceCellId();
const se = nifi.graph?.getCellById(sid);
const sen = se?.prop('name')
const ste = se?.prop('type');
const smd = se?.prop() || {};
const sig = isGroup(smd.name)
const scd = nifi.cells.get(sid);
const stype = sig ? DEFAULT_CELL_NAME.outputPorts.type : snakeCase(smd?.name.slice(0, -1)).toUpperCase();
const sPorts = reactive([])
const availableRelationships = scd?.component?.relationships?.map((d: any) => ({ label: d.name, desc: d.description, value: d.name })) || [];
sig && getGroupData(smd.name, sid, 'out', sPorts)
//
const sdr: string[] = []
if (sen == 'processors' && ste && nifi.cells.processors) {
    const { defaultRelations } = nifi.cells.processors.getMetadata(ste)
    if (defaultRelations) {
        sdr.push(...defaultRelations)
    }
}
// 目标节点
const tid = edge.getTargetCellId();
const te = nifi.graph?.getCellById(tid)
const tmd = te?.prop() || {};
const tig = isGroup(tmd.name)
const ttype = tig ? DEFAULT_CELL_NAME.inputPorts.type : snakeCase(tmd?.name.slice(0, -1)).toUpperCase();
const tPorts = reactive([])
tig && getGroupData(tmd.name, tid, 'in', tPorts)
// 提取表单需要的数据
const isDisabled = computed(() => nifi.graph.mode.value == 'prod' || disabled || smd?.status == DEFAULT_STATUS_NAME.Running.en);
// [PROCESSOR, REMOTE_INPUT_PORT, REMOTE_OUTPUT_PORT, INPUT_PORT, OUTPUT_PORT, FUNNEL]
const model = reactive({
    name: undefined,
    destination: { id: tig ? '' : tid, groupId: tig ? tid : groupId, type: ttype },
    source: { id: sig ? '' : sid, groupId: sig ? sid : groupId, type: stype },
    selectedRelationships: [...sdr],
    prioritizers: [],
    flowFileExpiration: "0 sec",
    backPressureObjectThreshold: "10000",
    backPressureDataSizeThreshold: "1 GB",
    loadBalanceCompression: "DO_NOT_COMPRESS",
    loadBalancePartitionAttribute: "",
    loadBalanceStrategy: "DO_NOT_LOAD_BALANCE",
})
// 初始化 model 的值
if (!isNew) {
    for (const k of Object.keys(model)) {
        if (has(cd.component, k)) {
            set(model, k, get(cd.component, k))
        }
    }
}
//
// 优先级设置器
const prioritizers = [
    "org.apache.nifi.prioritizer.OldestFlowFileFirstPrioritizer",
    "org.apache.nifi.prioritizer.PriorityAttributePrioritizer",
    "org.apache.nifi.prioritizer.FirstInFirstOutPrioritizer",
    "org.apache.nifi.prioritizer.NewestFlowFileFirstPrioritizer"
].map(v => ({ label: v.split('.').pop(), value: v }))

const loadBalanceStrategy = [
    { label: "do not load balance", value: "DO_NOT_LOAD_BALANCE" },
    { label: "partition by attribute", value: "PARTITION_BY_ATTRIBUTE" },
    { label: "round robin", value: "ROUND_ROBIN" },
    { label: "single node", value: "SINGLE_NODE" }
]

const loadBalanceCompression = [
    { value: "DO_NOT_COMPRESS", label: "do not compress" },
    { value: "COMPRESS_ATTRIBUTES_ONLY", label: "compress attributes only" },
    { value: "COMPRESS_ATTRIBUTES_AND_CONTENT", label: "compress attributes and content" },
]

// 表单校验
const elFormRef = ref()
const validateForm = async () => {
    try {
        await elFormRef.value.validate();
        return true;
    } catch (error) {
        ElMessage.warning(t('cells-connections-form-validate-failed', { error }))
        return false;
    }
}
// 调用接口新增边
const addConnections = async () => {
    try {
        const res = await nifi.cells.addCell(nifi.cells.connections.name, { component: model, revision: { clientId: nifi.flow.clientId, version: 0 } })
        nifi.cells.connections.add(res, edge);
        return true;
    } catch (error) {
        ElMessage.error(t('cells-connections-form-add-failed', { error }));
        console.error(error)
        return false;
    }

}
// 编辑 更新边
const editConnections = async () => {

    //
    const sd = cd.component;
    const d = diff(model, sd);
    //
    if (d == undefined) {
        ElMessage.info(t('cells-connections-form-unupdate'))
        closeDrawer();
        return true;
    }
    //
    const data = { component: { ...d, id }, revision: cd.revision };
    try {
        const res = await nifi.cells.setCell(edge, data)
        nifi.cells.connections.update(res)
        return true;
    } catch (error) {
        ElMessage.error(t('cells-connections-form-update-failed', { error }));
        console.error(error)
        return false;
    }


}

// 关闭 抽屉
const closeDrawer = () => {
    nifi.drawer.close();
}

const submitLoading = ref(false)
const handleSubmit = async () => {
    submitLoading.value = true;
    if (await validateForm()) {
        const b = await (isNew ? addConnections() : editConnections());
        if (b) {
            closeDrawer();
        }
    }
    submitLoading.value = false;
}

const handleCanel = () => {
    closeDrawer();
}

</script>

<template>
    <div class="w-full h-full flex flex-col ">
        <!-- header -->
        <div class="w-full overflow-hidden box-border flex justify-between items-center gap-8px m-b-16px h-40px min-h-40px">
            <div class="w-140px">
                <b>{{ isNew ? '新建边元素' : '编辑边元素' }}</b>
            </div>
            <div class="flex items-center overflow-hidden box-border p-x-16px flex-1">
                <!-- @vue-ignore -->
                <div class="flex items-center justify-end gap-8px"
                    :style="`color:${DEFAULT_STATUS_COLOR[smd.status]};min-width:calc(50% - 2em);`">
                    <!-- <i class="text-nowrap">( {{ smd.name }} )</i> -->
                    <b class="text-right truncate" style="" :title="`起始节点标签名：${smd.label}`"> {{ smd.label || smd.name
                        }}</b>
                </div>
                <div class="min-w-4em flex justify-center c-#67c23a">
                    <div class="i-tabler:arrow-big-up-filled w-1em h-1em rotate-90 scale-y-120"></div>
                </div>
                <div class="flex items-center gap-8"
                    :style="`color:${DEFAULT_STATUS_COLOR[tmd.status || 'Stopped']};min-width:calc(50% - 2em);`">
                    <b class="text-left truncate" :title="`目标节点标签名：${tmd.label}`">{{ tmd.label || tmd.name }}</b>
                    <!-- <i class="text-nowrap">( {{ smd.name }} )</i> -->
                </div>
            </div>
            <div class="w-140px flex justify-end">
                <template v-if="isDisabled">
                    <el-button plain type="primary" @click="handleCanel">确定</el-button>
                </template>
                <template v-else>

                    <el-button plain @click="handleCanel">取消</el-button>
                    <el-button type="primary" @click="handleSubmit" :loading="submitLoading">提交</el-button>
                </template>

            </div>
        </div>
        <ElTabs v-model="tabname" class="h-[calc(100%-40px)] w-full overflow-hidden">
            <ElTabPane :label="t('cells.connections.form.tab.property config')" name="property" class="h-full ">
                <!-- 表单 -->
                <el-form ref="elFormRef" :model="model" :disabled="isDisabled"
                    class="w-full box-border flex flex-col gap-8px overflow-y-auto overflow-x-hidden p-8px box-border scrollbar-0 text-14px"
                    label-width="130" label-position="left">
                    <!-- 处理组 -->
                    <div class="flex gap-24px w-full">
                        <fieldset class="p-12px p-t-2px rd-4px b-gray-300 b-solid box-border min-w-0"
                            style="width:calc(50% - 2em)">
                            <!-- @vue-skip -->
                            <legend class="max-w-200px fw-bold truncate"
                                :style="`color:${DEFAULT_STATUS_COLOR[smd.status]};`">
                                {{ smd.label || smd.name }} [ {{ DEFAULT_CELL_NAME[smd.name].cn }} ]
                            </legend>
                            <template v-if="sig">
                                <el-form-item required label="输出端口" prop="source.id" label-width="100">
                                    <ElSelectV2 :options="sPorts" v-model="model.source.id"></ElSelectV2>
                                </el-form-item>
                            </template>
                            <template v-else>
                                <el-form-item v-if="availableRelationships.length > 0" label="输出关系"
                                    prop="selectedRelationships" required label-width="100">
                                    <ElCheckboxGroup v-model="model.selectedRelationships">
                                        <ElCheckbox v-for="item in availableRelationships" :title="item.desc"
                                            :value="item.label" :label="item.label"></ElCheckbox>
                                    </ElCheckboxGroup>
                                </el-form-item>
                                <!-- @vue-ignore -->
                                <div v-else class="fw-bold" :style="`color:${DEFAULT_STATUS_COLOR[smd.status]};`">{{
                                    smd.label || smd.name }}</div>
                            </template>
                            <div v-if="false" class="w-full flex flex-col justify-around">
                                <span class="w-full flex items-center ">
                                    <span class="min-w-100px">标签名</span>
                                    <!-- @vue-ignore -->
                                    <b class="truncate" :style="`color:${DEFAULT_STATUS_COLOR[smd.status]};`"
                                        :title="smd.label"> {{
                                            smd.label }}</b>
                                </span>
                                <span class="w-full flex items-center ">
                                    <span class="min-w-100px">类型</span>
                                    <!-- @vue-skip -->
                                    <b class="truncate" :style="`color:${DEFAULT_STATUS_COLOR[smd.status]};`"> {{
                                        DEFAULT_CELL_NAME[smd.name].cn }}</b>
                                </span>
                            </div>
                        </fieldset>
                        <div class="flex justify-center items-center c-#67c23a">
                            <div class="i-tabler:arrow-big-up-filled w-1em h-1em rotate-90 scale-y-120"></div>
                        </div>
                        <fieldset class="p-12px p-t-2px rd-4px b-gray-300 b-solid box-border min-w-0"
                            style="width:calc(50% - 2em)">
                            <!-- @vue-skip -->
                            <legend class="max-w-200px fw-bold truncate"
                                :style="`color:${DEFAULT_STATUS_COLOR[tmd.status || 'Stopped']};`">
                                {{ tmd.label || tmd.name }} [ {{ DEFAULT_CELL_NAME[tmd.name].cn }} ]
                            </legend>
                            <div v-if="tig">
                                <el-form-item required prop="destination.id" label="接入端口" label-width="100">
                                    <ElSelectV2 :options="tPorts" v-model="model.destination.id"></ElSelectV2>
                                </el-form-item>
                            </div>

                            <div v-else class="w-full flex flex-col justify-around">
                                <span class="w-full flex items-center ">
                                    <span class="min-w-100px">状态</span>
                                    <!-- @vue-ignore -->
                                    <b class="truncate" :style="`color:${DEFAULT_STATUS_COLOR[tmd.status]};`"
                                        :title="tmd.label">
                                        {{ tmd.status }}
                                    </b>
                                </span>
                                <span v-if="false" class="w-full flex items-center ">
                                    <span class="min-w-100px">类型</span>
                                    <!-- @vue-skip -->
                                    <b class="truncate" :style="`color:${DEFAULT_STATUS_COLOR[tmd.status]};`"> {{
                                        DEFAULT_CELL_NAME[tmd.name].cn }}</b>
                                </span>
                            </div>
                        </fieldset>
                    </div>

                    <!-- <div class="min-h-1 bg-gray-200 m-y-4"></div> -->
                    <fieldset class="p-12px p-t-2px rd-4px b-gray-300 b-solid gap-x-24px grid grid-cols-2">
                        <legend>配置</legend>
                        <ElFormItem label="标签名称" prop="name">
                            <ElInput v-model="model.name"></ElInput>
                        </ElFormItem>
                        <ElFormItem label="优先级设置器" prop="prioritizers">
                            <ElSelectV2 v-model="model.prioritizers" :options="prioritizers" multiple collapse-tags>
                            </ElSelectV2>
                        </ElFormItem>
                        <ElFormItem label="队列记录阈值" prop="backPressureObjectThreshold">
                            <ElInput v-model="model.backPressureObjectThreshold"></ElInput>
                        </ElFormItem>
                        <ElFormItem label="FlowFile 过期时间" prop="flowFileExpiration">
                            <ElInput v-model="model.flowFileExpiration"></ElInput>
                        </ElFormItem>
                        <ElFormItem label="队列大小阈值" prop="backPressureDataSizeThreshold">
                            <ElInput v-model="model.backPressureDataSizeThreshold"></ElInput>
                        </ElFormItem>
                        <ElFormItem label="负载均衡策略" prop="loadBalanceStrategy">
                            <ElSelectV2 v-model="model.loadBalanceStrategy" :options="loadBalanceStrategy"></ElSelectV2>
                        </ElFormItem>
                        <ElFormItem label="属性名称" prop="loadBalancePartitionAttribute"
                            v-if="model.loadBalanceStrategy != 'PARTITION_BY_ATTRIBUTE'">
                            <ElInput v-model="model.loadBalancePartitionAttribute"></ElInput>
                        </ElFormItem>
                        <ElFormItem label="负载均衡压缩" prop="loadBalanceCompression"
                            v-if="model.loadBalanceStrategy != 'DO_NOT_LOAD_BALANCE'">
                            <ElSelectV2 v-model="model.loadBalanceCompression" :options="loadBalanceCompression">
                            </ElSelectV2>
                        </ElFormItem>
                    </fieldset>

                    <!--  -->
                </el-form>
            </ElTabPane>
            <ElTabPane :label="t('cells.connections.form.tab.quene list')" name="quene" class="h-full">
                <nifi.Quene.ListEl :nifi="nifi" :id="id" v-if="tabname == 'quene'"></nifi.Quene.ListEl>
            </ElTabPane>

            <ElTabPane label="test" name="test">
                <HexEl></HexEl>
            </ElTabPane>
        </ElTabs>

    </div>
</template>